package com.zudada.servermain.Service.ServiceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zudada.servermain.POJO.DTO.VesselBerthingAddDTO;
import com.zudada.servermain.POJO.DTO.VesselBerthingPageQueryDTO;
import com.zudada.servermain.POJO.DTO.VesselBerthingUpdateDTO;
import com.zudada.servermain.POJO.VO.PageResult;
import com.zudada.servermain.POJO.entity.VesselBerthing;
import com.zudada.servermain.Service.VesselBerthingService;
import com.zudada.servermain.exception.BusinessException;
import com.zudada.servermain.mapper.VesselBerthingMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;

@Service
@Slf4j
public class VesselBerthingServiceImpl implements VesselBerthingService {

    @Autowired
    private VesselBerthingMapper vesselBerthingMapper;

    @Override
    public boolean addVesselBerthing(VesselBerthingAddDTO dto) {
        // 参数验证
        if (dto == null) {
            throw new BusinessException("船舶停靠数据不能为空");
        }

        try {
            VesselBerthing vb = new VesselBerthing();
            BeanUtils.copyProperties(dto, vb);

            int result = vesselBerthingMapper.insert(vb);
            if (result <= 0) {
                log.error("添加船舶停靠记录失败，插入结果：{}", result);
                throw new BusinessException("添加船舶停靠记录失败");
            }
            return true;
        } catch (DataIntegrityViolationException e) {
            log.error("添加船舶停靠记录失败，数据完整性约束异常：{}", e.getMessage(), e);
            throw new BusinessException("添加失败，数据已存在或存在关联关系");
        } catch (Exception e) {
            log.error("添加船舶停靠记录异常：{}", e.getMessage(), e);
            throw new BusinessException("添加船舶停靠记录失败：" + e.getMessage());
        }
    }

    /**
     * 根据id删除数据
     * @param id
     */
    @Override
    public boolean deleteById(String id) {
        // 参数验证
        if (id == null || id.trim().isEmpty()) {
            throw new BusinessException("停靠记录ID不能为空");
        }

        try {
            // 判断是否存在该条记录
            VesselBerthing existingBerthing = vesselBerthingMapper.selectById(id);
            if (existingBerthing == null) {
                throw new BusinessException("当前停靠记录不存在，无法删除");
            }

            int result = vesselBerthingMapper.deleteById(id);
            if (result <= 0) {
                log.error("删除船舶停靠记录失败，删除结果：{}", result);
                throw new BusinessException("删除船舶停靠记录失败");
            }
            return true;
        } catch (DataIntegrityViolationException e) {
            log.error("删除船舶停靠记录失败，数据完整性约束异常：{}", e.getMessage(), e);
            throw new BusinessException("删除失败，该记录存在关联数据，请先删除关联数据");
        } catch (BusinessException e) {
            // 重新抛出业务异常
            throw e;
        } catch (Exception e) {
            log.error("删除船舶停靠记录异常：{}", e.getMessage(), e);
            throw new BusinessException("删除船舶停靠记录失败：" + e.getMessage());
        }
    }
    /**
     * 修改船舶停靠数据
     */
    @Override
    public void updateVesselBerthing(VesselBerthingUpdateDTO dto) {
        // 参数验证
        if (dto == null) {
            throw new BusinessException("船舶停靠更新数据不能为空");
        }

        // 判断berth_id不能为空
        String bi = dto.getBerthId();
        if (bi == null || bi.trim().isEmpty()) {
            throw new BusinessException("停靠记录唯一标识不能为空");
        }

        try {
            // 判断记录是否存在
            VesselBerthing existingBerthing = vesselBerthingMapper.selectById(bi);
            if (existingBerthing == null) {
                throw new BusinessException("当前停靠记录不存在，berthId：" + bi);
            }

            VesselBerthing vb = new VesselBerthing();
            BeanUtils.copyProperties(dto, vb);

            int result = vesselBerthingMapper.updateById(vb);
            if (result <= 0) {
                log.error("更新船舶停靠记录失败，更新结果：{}", result);
                throw new BusinessException("更新船舶停靠记录失败");
            }
        } catch (DataIntegrityViolationException e) {
            log.error("更新船舶停靠记录失败，数据完整性约束异常：{}", e.getMessage(), e);
            throw new BusinessException("更新失败，数据存在关联关系或违反唯一约束");
        } catch (BusinessException e) {
            // 重新抛出业务异常
            throw e;
        } catch (Exception e) {
            log.error("更新船舶停靠记录异常：{}", e.getMessage(), e);
            throw new BusinessException("更新船舶停靠记录失败：" + e.getMessage());
        }
    }

    /**
     * 分页查询船舶停靠数据
     * @param queryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(VesselBerthingPageQueryDTO queryDTO) {
        // 参数验证
        if (queryDTO == null) {
            throw new BusinessException("查询参数不能为空");
        }

        try {
            // 参数解析
            int pageNum = queryDTO.getPage();
            int pageSize = queryDTO.getPageSize();

            // 分页参数验证
            if (pageNum < 1) {
                throw new BusinessException("页码必须大于0");
            }
            if (pageSize < 1) {
                throw new BusinessException("每页数量必须大于0");
            }
            if (pageSize > 1000) {
                throw new BusinessException("每页数量不能超过1000");
            }

            // 时间范围验证
            Date berthTimeStart = queryDTO.getBerthTimeStart();
            Date berthTimeEnd = queryDTO.getBerthTimeEnd();
            if (berthTimeStart != null && berthTimeEnd != null && berthTimeStart.after(berthTimeEnd)) {
                throw new BusinessException("开始时间不能晚于结束时间");
            }

            // 构造分页对象
            Page<VesselBerthing> page = new Page<>(pageNum, pageSize);
            // 构造查询条件
            LambdaQueryWrapper<VesselBerthing> queryWrapper = new LambdaQueryWrapper<>();

            // 2.1 字符串类型条件：非空且非空字符串才添加（模糊查询/精确查询按需调整）
            if (StringUtils.hasText(queryDTO.getVesselName())) {
                queryWrapper.like(VesselBerthing::getVesselName, queryDTO.getVesselName()); // 船舶名称模糊查询
            }
            if (StringUtils.hasText(queryDTO.getPortId())) {
                queryWrapper.eq(VesselBerthing::getPortId, queryDTO.getPortId()); // 港口ID精确匹配
            }
            if (StringUtils.hasText(queryDTO.getBerthId())) {
                queryWrapper.eq(VesselBerthing::getBerthId, queryDTO.getBerthId()); // 泊位ID精确匹配
            }
            if (StringUtils.hasText(queryDTO.getVesselId())) {
                queryWrapper.eq(VesselBerthing::getVesselId, queryDTO.getVesselId()); // 船舶ID精确匹配
            }
            if (StringUtils.hasText(queryDTO.getVesselType())) {
                queryWrapper.eq(VesselBerthing::getVesselType, queryDTO.getVesselType()); // 船舶类型精确匹配
            }
            if (StringUtils.hasText(queryDTO.getStatus())) {
                queryWrapper.eq(VesselBerthing::getStatus, queryDTO.getStatus()); // 状态精确匹配
            }

            // 2.2 时间范围查询（berthTimeStart ~ berthTimeEnd 区间）
            if (berthTimeStart != null && berthTimeEnd != null) {
                queryWrapper.between(VesselBerthing::getBerthTime, berthTimeStart, berthTimeEnd);
            } else if (berthTimeStart != null) {
                queryWrapper.ge(VesselBerthing::getBerthTime, berthTimeStart); // 大于等于开始时间
            } else if (berthTimeEnd != null) {
                queryWrapper.le(VesselBerthing::getBerthTime, berthTimeEnd); // 小于等于结束时间
            }

            // 2.3 精确时间查询（单独匹配 berthTime / departureTime）
            if (queryDTO.getBerthTime() != null) {
                queryWrapper.eq(VesselBerthing::getBerthTime, queryDTO.getBerthTime());
            }
            if (queryDTO.getDepartureTime() != null) {
                queryWrapper.eq(VesselBerthing::getDepartureTime, queryDTO.getDepartureTime());
            }

            // 3. 执行分页查询（MyBatis-Plus 内置 selectPage 方法，自动分页）
            Page<VesselBerthing> resultPage = this.vesselBerthingMapper.selectPage(page, queryWrapper);

            PageResult pageResult = new PageResult();
            pageResult.setTotal(resultPage.getTotal());
            pageResult.setRecords(resultPage.getRecords());
            return pageResult;
        } catch (BusinessException e) {
            // 重新抛出业务异常
            throw e;
        } catch (Exception e) {
            log.error("分页查询船舶停靠记录异常：{}", e.getMessage(), e);
            throw new BusinessException("查询船舶停靠记录失败：" + e.getMessage());
        }
    }

}
